//! Header for the RemoteControl class
#ifndef REMOTECONTROL_H
#define REMOTECONTROL_H

#include <vector>
#include "Object.h"
#include "ICommand.h"

//! structure representing a Slot
/*!
	The slot is made of an on command
	and an off command and the name of the
	device executing these commands.
*/
struct Slot{
   /** The On-Command */
	ICommand* onCmd;
   /** The Off-Command */
	ICommand* offCmd;
   /** The Device Name */
	std::string deviceName;
};
//typedef for a vector of data type Slot
typedef std::vector<Slot> TSlots;

//! RemoteControl is able to remotely command devices it is programmed for
/*!
	The class RemoteControl has 6 programmable slots for 6 devices.
	At construction, all slots are assigned with the NoCommand object
	(does nothing). A slot can be overwritten (no warning will occur).
	It is able to call certain commands when the "ON" button is pressed
	or when the "OFF" button is pressed and it can also undo the last
	executed command.
	\class RemoteControl
	\author Andreas Lehner
	\date 25.11.2012
*/
class RemoteControl : public Object {
public:
	//! CTor of class RemoteControl
	/*!
		In the constructor every slot is assigned
		with a NoCommand object, which is doing
		nothing. The on and the off command will
		be affected. It also sets the number of slots
		a remote control has (6).
	*/
	RemoteControl();
	//! Function to execute the on command of a slot
	/*!
		The on command of the given slot is output
		and this command is set as the last command
		for undoing it.
		\param slotNr The slot number where the command is executed
		\throw exception If the committed slot number is higher than mNrOfSlots-1
	*/
	void OnButtonPressed(size_t slotNr);
	//! Function to execute the off command of a slot
	/*!
		The off command of the given slot is output
		and this command is set as the last command
		for undoing it.
		\param slotNr The slot number where the command is executed
		\throw exception If the committed slot number is higher than mNrOfSlots-1
	*/
	void OffButtonPressed(size_t slotNr);
	//! Undo the last executed command
	/*!
		The last command is saved in a member
		for which execute is called.
	*/
	void UndoButtonPressed();
	//! Program a slot of the remote control
	/*!
		The slot of the remote control will be programmed by setting its
		on and its off command. If the slot is currently programmed by other
		commands they will be overwritten. Also the device name will be set
		to give the programmed slot a name for later output as there maybe more
		than one TV's why the ability for naming them differently is given.
		\param slotNr The slot number where the commands will be programmed
		\param onCmd The on command of the slot
		\param offCmd The off command of the slot
		\param devname The name of the device that will execute the commands
		\throw exception If the committed slot number is higher than mNrOfSlots-1
		\throw exception If the pointers of onCmd and/or offCmd is 0
	*/
	void ProgramSlot(size_t slotNr, ICommand* onCmd, ICommand* offCmd, std::string const devname);
	//! Function to return the number of slots
	/*!
		This function returns the number of the slots of a
		remote control. This value is set internally while construction.
		\return size_t The number of slots
	*/
	size_t const GetNrOfSlots() const;
	//! Function to return the name of a programmed device
	/*!
		This function returns the name of a device at a certain slot and
		is used for output.
		\throw exception If the committed slot number is higher than mNrOfSlots-1
		\return std::string The name of the device
	*/
	std::string const GetDeviceName(size_t slotNr) const;
private:
	//vector of slots
	TSlots mSlots;
	//number of the slots
	size_t mNrOfSlots;
	//last command used for undo function
	ICommand * mLastcmd;
};

#endif